<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>顶点着色器和片段着色器</title>
  <style>
    *,
    *::after,
    *::before {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    :root {
      min-height: 100vh;
    }

    :root:focus-within {
      scroll-behavior: smooth;
    }

    body {
      min-height: inherit;
    }
  </style>
</head>

<body>
</body>
<script>
  "use strict"; {
    const Canvas = document.createElement("canvas")
    document.body.appendChild(Canvas)
    Canvas.width = 400
    Canvas.height = 300

    const GL = Canvas.getContext("webgl2")
    if (!GL) throw new Error("浏览器不支持webgl2")


    // 创建shader
    let createShader = (source, type = "VERTEX_SHADER") => {
      // 创建顶点着色器
      let shader = GL.createShader(GL[type])
      GL.shaderSource(shader, source)

      // 编译着色器
      GL.compileShader(shader)

      // 获取shader的编译状态
      let success = GL.compileShader(shader, GL.COMPILE_STATUS)
      // 如果编译成功了，直接返回shader
      if (success) return shader

      // 删除编译失败的着色器
      GL.deleteShader(shader)
      // 打印出错误的消息
      console.error(GL.getShaderInfoLog(shader))
    }


    // 创建着色程序
    let createProgram = (verTextShader, fragMentShader) => {
      let program = GL.createProgram()
      GL.attachShader(program, verTextShader)
      GL.attachShader(program, fragMentShader)
      GL.linkProgram(program)
      let success = GL.getProgramParameter(program, GL.LINK_STATUS)

      if (success) return program

      console.error(GL.getProgramInfoLog(program))
      GL.deleteProgram(program)
    }

    // 顶点着色文本源
    const verTextSource = `
      attribute vec2 a;

      void main() {
        glPosition = vec4(a,0,0,1.0);
      }
    `
    const verTextShader = createShader(verTextSource)

    // 创建顶点坐标
    let position = [
      0, 0,
      0, 0.5,
      0.7, 0
    ]

    // 创建顶点缓冲器
    const verTextBuffer = GL.createBuffer()
    GL?.bindBuffer(GL.ARRAY_BUFFER, verTextBuffer)
    GL.bufferData(GL.ARRAY_BUFFER, new Float32Array(position), GL.STATIC_DRAW)

    // 片源着色器
    const fragMentSource = `
      precision mediump float;

      void main() {
        color = vec4(1,0,0.5,1.0)
      }
    `
    let fragMentShader = createShader(fragMentSource, "FRAGMENT_SHADER")

    // 将顶点着色器和片源着色器绑定到着色程序上
    let program = createProgram(verTextShader, fragMentShader)
  };  
</script>

</html>